﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using JXT.PrimaryKey.Batman.Domain.Quotation.Models;
using JXT.PrimaryKey.Batman.Domain.Quotation.Repositories;
using JXT.PrimaryKey.Batman.Domain.Repositories.MySql;

namespace JXT.PrimaryKey.Batman.Domain.Repositories.Quotation
{
    public class MySqlRealTimeQuoteRepository : MySqlRepositoryBase<RealTimeQuote, Guid>, IRealTimeQuoteRepository
    {
        public MySqlRealTimeQuoteRepository(RepositoryContext context)
            : base((MySqlRepositoryContext)context)
        {
        }

        public override void Add(RealTimeQuote entity)
        {
            string sql = "select count(*) from `realtimequote` where `code`=@code and `markettype`=@markettype and `updatetime`=@updatetime";
            var parameterArray = new[]{
                Context.CreateParameter("@code", entity.Code),
                Context.CreateParameter("@markettype", entity.MarketType),
                Context.CreateParameter("@updatetime", entity.UpdateTime)
            };
            int count = Convert.ToInt32(Context.ExecuteScalar(sql, parameterArray));
            if (count > 0)
            {
                sql = @"update `realtimequote` set 
                            `lastprice`=@lastprice, 
                            `tradingvolume`=@tradingvolume, 
                            `turnover`=@turnover, 
                            `openprice`=@openprice, 
                            `prevcloseprice`=@prevcloseprice,
                            `highestprice`=@highestprice,
                            `lowestprice`=@lowestprice,
                            `buyprice1`=@buyprice1,
                            `buyprice2`=@buyprice2,
                            `buyprice3`=@buyprice3,
                            `buyprice4`=@buyprice4,
                            `buyprice5`=@buyprice5,
                            `buyvolume1`=@buyvolume1,
                            `buyvolume2`=@buyvolume2,
                            `buyvolume3`=@buyvolume3,
                            `buyvolume4`=@buyvolume4,
                            `buyvolume5`=@buyvolume5,
                            `sellprice1`=@sellprice1,
                            `sellprice2`=@sellprice2,
                            `sellprice3`=@sellprice3,
                            `sellprice4`=@sellprice4,
                            `sellprice5`=@sellprice5,
                            `sellvolume1`=@sellvolume1,
                            `sellvolume2`=@sellvolume2,
                            `sellvolume3`=@sellvolume3,
                            `sellvolume4`=@sellvolume4,
                            `sellvolume5`=@sellvolume5,
                            `pe`=@pe
                        where 
                            `code`=@code and `markettype`=@markettype and `updatetime`=@updatetime";
                var updateParameterArray = new[]{
                    Context.CreateParameter("@lastprice", entity.LastPrice),
                    Context.CreateParameter("@tradingvolume", entity.TradingVolume),
                    Context.CreateParameter("@turnover", entity.Turnover),
                    Context.CreateParameter("@openprice", entity.OpenPrice),
                    Context.CreateParameter("@prevcloseprice", entity.PrevClosePrice),
                    Context.CreateParameter("@highestprice", entity.HighestPrice),
                    Context.CreateParameter("@lowestprice", entity.LowestPrice),
                    Context.CreateParameter("@buyprice1", entity.BuyPrice1),
                    Context.CreateParameter("@buyprice2", entity.BuyPrice2),
                    Context.CreateParameter("@buyprice3", entity.BuyPrice3),
                    Context.CreateParameter("@buyprice4", entity.BuyPrice4),
                    Context.CreateParameter("@buyprice5", entity.BuyPrice5),
                    Context.CreateParameter("@buyvolume1", entity.BuyVolume1),
                    Context.CreateParameter("@buyvolume2", entity.BuyVolume2),
                    Context.CreateParameter("@buyvolume3", entity.BuyVolume3),
                    Context.CreateParameter("@buyvolume4", entity.BuyVolume4),
                    Context.CreateParameter("@buyvolume5", entity.BuyVolume5),
                    Context.CreateParameter("@sellprice1", entity.SellPrice1),
                    Context.CreateParameter("@sellprice2", entity.SellPrice2),
                    Context.CreateParameter("@sellprice3", entity.SellPrice3),
                    Context.CreateParameter("@sellprice4", entity.SellPrice4),
                    Context.CreateParameter("@sellprice5", entity.SellPrice5),
                    Context.CreateParameter("@sellvolume1", entity.SellVolume1),
                    Context.CreateParameter("@sellvolume2", entity.SellVolume2),
                    Context.CreateParameter("@sellvolume3", entity.SellVolume3),
                    Context.CreateParameter("@sellvolume4", entity.SellVolume4),
                    Context.CreateParameter("@sellvolume5", entity.SellVolume5),
                    Context.CreateParameter("@pe", entity.PE),
                    Context.CreateParameter("@code", entity.Code),
                    Context.CreateParameter("@markettype", entity.MarketType),
                    Context.CreateParameter("@updatetime", entity.UpdateTime)
                };
                Context.ExecuteNonQuery(sql, updateParameterArray);
            }
            else
            {
                base.Add(entity);
            }
        }

        public void Add(IEnumerable<RealTimeQuote> list)
        {
            foreach (var item in list)
            {
                Add(item);
            }
        }

        public int Count(MarketType type, DateTime date)
        {
            string sql = "select count(*) from `realtimequote` where `markettype`=@markettype and `updatetime`=@updatetime";
            var parameterArray = new[]{
                Context.CreateParameter("@markettype", type),
                Context.CreateParameter("@updatetime", date)
            };
            int result = Convert.ToInt32(Context.ExecuteScalar(sql, parameterArray));
            return result;
        }

        public RealTimeQuote GetSingle(string code, MarketType type = MarketType.Unknown, DateTime? date = null)
        {
            string sql = "select * from `realtimequote` where `code`=@code and `markettype`=@markettype";
            IList<IDataParameter> parameterList = new List<IDataParameter>();
            parameterList.Add(Context.CreateParameter("@code", code));
            parameterList.Add(Context.CreateParameter("@markettype", type));
            if (date != null)
            {
                sql += " and `updatetime`=@updatetime";
                parameterList.Add(Context.CreateParameter("@updatetime", date.Value));
            }
            RealTimeQuote result = null;
            using (var dr = Context.ExecuteDataReader(sql, parameterList.ToArray()))
            {
                if (dr.Read())
                {
                    result = ReadEntityFromDataReader(dr);
                }
            }
            return result;
        }

        public IEnumerable<RealTimeQuote> GetList(string code, MarketType type = MarketType.Unknown, DateTime? startTime = null, DateTime? endTime = null)
        {
            string sql = "select * from `realtimequote` where `code`=@code and `markettype`=@markettype";
            IList<IDataParameter> parameterList = new List<IDataParameter>();
            parameterList.Add(Context.CreateParameter("@code", code));
            parameterList.Add(Context.CreateParameter("@markettype", type));
            if (startTime != null)
            {
                sql += " and `updatetime`>=@starttime";
                parameterList.Add(Context.CreateParameter("@starttime", startTime.Value));
            }
            if (endTime != null)
            {
                sql += " and `updatetime`<@endtime";
                parameterList.Add(Context.CreateParameter("@endtime", endTime.Value));
            }
            sql += " order by `updatetime` desc";
            IList<RealTimeQuote> list = new List<RealTimeQuote>();
            using (var dr = Context.ExecuteDataReader(sql, parameterList.ToArray()))
            {
                while (dr.Read())
                {
                    list.Add(ReadEntityFromDataReader(dr));
                }
            }
            return list;
        }
    }
}
